package top.canyue.eca_manager.service.impl;

import com.alibaba.fastjson2.JSON;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import top.canyue.eca_manager.bean.Result;
import top.canyue.eca_manager.bean.User;
import top.canyue.eca_manager.mapper.UserMapper;
import top.canyue.eca_manager.service.LogService;
import top.canyue.eca_manager.service.UserService;
import top.canyue.eca_manager.tool.ParamTools;

import java.util.*;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogService logService;

    @Override
    public Result findById(String id) {
        Result result = new Result();
        if(id.isEmpty()){
            result.setStatus(500);
            result.setMsg("ID不得为空");
            return result;
        }
        User user = userMapper.findById(id);
        if (user == null){
            result.setStatus(500);
            result.setMsg("用户不存在");
        }else{
            result.setStatus(200);
            result.setMsg("OK");
            result.setData(user);
        }
        return result;
    }

    @Override
    public Result findByName(String name, String orders, Integer offset, Integer fetchSize) {
        Result result = new Result();
        List<User> users;
        if (name.isEmpty()) {
            users = userMapper.findAll(orders, offset, fetchSize);
        } else {
            if (offset < 0) {
                result.setStatus(500);
                result.setMsg("偏移量不得小于0");
                return result;
            }
            if (fetchSize < 1) {
                result.setStatus(500);
                result.setMsg("一页大小不得小于1");
                return result;
            }
            orders = orders.isEmpty() ? "createTime ASC" : orders;
            users = userMapper.findByName(name, orders, offset, fetchSize);
        }
        if (users.size() > 0) {
            result.setStatus(200);
            result.setMsg("OK");
            result.setData(users);
        } else {
            result.setStatus(200);
            result.setMsg("查询结果为空");
        }
        return result;
    }

    @Override
    public Result getUserCountByName(String name) {
        Result result = new Result();
        Integer count;
        if (name.isEmpty()) {
            count = userMapper.getUserCountAll();
            result.setMsg("OK");
            result.setStatus(200);
            result.setData(count);
        } else {
            count = userMapper.getUserCountByName(name);
            result.setMsg("OK");
            result.setStatus(200);
            result.setData(count);
        }
        return result;
    }

    @Override
    public Result login(String idOrName, String passwd) {
        Result result = new Result();
        if(idOrName.isEmpty() || passwd.isEmpty()){
            result.setStatus(500);
            result.setMsg("用户名或密码不得为空");
            return result;
        } else if (ParamTools.containsSqlInjection(idOrName) || ParamTools.containsSqlInjection(passwd)) {
            result.setStatus(500);
            result.setMsg("疑似SQL注入攻击,你的操作已被系统记录！");
            logService.record(null, "WARN", "SQLInject", ParamTools.paramsToJsonString(idOrName, passwd), result.getStatus());
            return result;
        }
        String md5Passwd = DigestUtils.md5DigestAsHex(passwd.getBytes());

        User user = userMapper.login(idOrName, md5Passwd);
        if(user == null){
            result.setStatus(500);
            result.setMsg("用户名或密码错误");
        }else{
            result.setStatus(200);
            result.setMsg("OK");
            result.setData(user);
        }

        if (user != null) {
            logService.record(user.getId(), "INFO", "login", JSON.toJSONString(user), result.getStatus());
        } else {
            logService.record(null, "WARN", "login", ParamTools.paramsToJsonString(idOrName, passwd), result.getStatus());
        }
        return result;
    }

    @Override
    public Result logon(String name, String passwd, String phone) {
        Result result = new Result();
        System.out.println(phone.length());

        if (ParamTools.containsSqlInjection(name) || ParamTools.containsSqlInjection(passwd) || ParamTools.containsSqlInjection(phone)) {
            result.setStatus(500);
            result.setMsg("疑似SQL注入，你的操作已被记录！");
            logService.record(null, "WARN", "SQLInject", ParamTools.paramsToJsonString(name, phone, passwd), result.getStatus());
            return result;
        }

        if(name.isEmpty() || passwd.isEmpty()){
            result.setStatus(500);
            result.setMsg("用户名或密码不得为空");
            return result;
        } else if (passwd.length() < 6) {
            result.setStatus(500);
            result.setMsg("密码长度必须大于等于6位");
            return result;
        } else if (phone.isEmpty()) {
            result.setStatus(500);
            result.setMsg("手机号不得为空");
            return result;
        } else if (phone.length() != 11) {
            result.setStatus(500);
            result.setMsg("手机号必须为11位");
            return result;
        }

        User user = new User();
        UUID uuid = UUID.randomUUID();
        String uuidStr = StringUtils.remove(uuid.toString(), '-');
        user.setId(uuidStr);
        user.setName(name);
        String md5Passwd = DigestUtils.md5DigestAsHex(passwd.getBytes());
        user.setPasswd(md5Passwd);
        user.setPhone(phone);
        boolean pass;
        try {
            pass = userMapper.addUser(user) == 1;

        } catch (DuplicateKeyException duplicateKeyException) {
            result.setStatus(500);
            result.setMsg("用户注册信息已存在");
            return result;
        } catch (Exception exception) {
            result.setStatus(500);
            result.setMsg("服务器错误");
            return result;
        }

        if (!pass) {
            result.setStatus(500);
            result.setMsg("注册失败");
            return result;
        }
        Map<String, String> data = new HashMap<>();
        data.put("id", uuidStr);
        result.setStatus(200);
        result.setMsg("OK");
        result.setData(data);
        logService.record(user.getId(),
                result.getStatus() == 200 ? "INFO" : "ERROR"
                , "logon", JSON.toJSONString(user), result.getStatus());
        return result;
    }

    @Override
    public Result updateUserInfo(User user) {
        Result result = new Result();
        if (user.getId().isEmpty()) {
            result.setStatus(500);
            result.setMsg("用户id不得为空");
            return result;
        }

        if (user.getName().isEmpty()) {
            result.setStatus(500);
            result.setMsg("用户名不得为空");
            return result;
        }

        if (user.getPhone().isEmpty()) {
            result.setStatus(500);
            result.setMsg("手机号不得为空");
            return result;
        } else if (user.getPhone().length() != 11) {
            result.setStatus(500);
            result.setMsg("手机号必须为11位");
            return result;
        }

        boolean pass = userMapper.updateUserInfo(user) == 1;
        if (pass) {
            result.setStatus(200);
            result.setMsg("OK");
        } else {
            result.setStatus(500);
            result.setMsg("内部错误_可能由不存在的ID引发");
        }
        logService.record(user.getId(),
                result.getStatus() == 200 ? "INFO" : "ERROR"
                , "updateUserInfo", JSON.toJSONString(user), result.getStatus());
        return result;
    }

    @Override
    public Result updateUserPasswd(String id, String oldPasswd, String newPasswd) {
        Result result = new Result();
        if (Objects.equals(id, "")) {
            result.setStatus(500);
            result.setMsg("用户id不得为空");
            return result;
        } else if (Objects.equals(oldPasswd, "") || Objects.equals(newPasswd, "")) {
            result.setStatus(500);
            result.setMsg("密码不得为空");
            return result;
        } else if (ParamTools.containsSqlInjection(id) || ParamTools.containsSqlInjection(oldPasswd) || ParamTools.containsSqlInjection(newPasswd)) {
            result.setStatus(500);
            result.setMsg("已拦截疑似SQL注入攻击,你的操作已被记录！");
            return result;
        }
        if (Objects.equals(oldPasswd, newPasswd)) {
            result.setStatus(500);
            result.setMsg("新密码不得与旧密码相同");
            return result;
        } else if (newPasswd.length() < 6) {
            result.setStatus(500);
            result.setMsg("密码必须大于6位数");
            return result;
        }
        String md5OldPasswd = DigestUtils.md5DigestAsHex(oldPasswd.getBytes());
        String md5NewPasswd = DigestUtils.md5DigestAsHex(newPasswd.getBytes());
        boolean pass = userMapper.updateUserPasswd(id, md5OldPasswd, md5NewPasswd) == 1;
        if (pass) {
            result.setStatus(200);
            result.setMsg("OK");
        } else {
            result.setStatus(500);
            result.setMsg("更新失败，请检查旧密码是否正确");
        }
        logService.record(id,
                result.getStatus() == 200 ? "INFO" : "ERROR"
                , "updateUserPasswd", JSON.toJSONString(id), result.getStatus());
        return result;
    }

    @Override
    public Result deleteUser(String id) {
        Result result = new Result();
        if (id == null) {
            result.setStatus(500);
            result.setMsg("用户id不得为空");
            return result;
        }
        boolean pass = userMapper.deleteUser(id) == 1;
        if (pass) {
            result.setStatus(200);
            result.setMsg("OK");
        } else {
            result.setStatus(500);
            result.setMsg("删除失败,请检查用户是否存在");
        }
        //设计缺陷，目前被法记录被谁删除的，后续可能会在请求头上做手脚
        logService.record(id,
                result.getStatus() == 200 ? "WARN" : "ERROR"
                , "deleteUser", JSON.toJSONString(id), result.getStatus());
        return result;
    }

    @Override
    public Result updateUserAdmin(String id, boolean admin) {
        Result result = new Result();
        if (id == null) {
            result.setStatus(500);
            result.setMsg("用户id不得为空");
            return result;
        }
        boolean pass = userMapper.updateUserAdmin(id, admin ? 1 : 0) == 1;
        if (pass) {
            result.setStatus(200);
            result.setMsg("OK");
        } else {
            result.setStatus(500);
            result.setMsg("更新失败,请检查用户是否存在");
        }
        logService.record(id,
                result.getStatus() == 200 ? "INFO" : "ERROR"
                , "updateUserAdmin", ParamTools.paramsToJsonString(id, admin), result.getStatus());
        return result;
    }

    @Override
    public Result getUserCount(){
        Result result = new Result();
        Integer count = userMapper.getUserCount();
        if(count >= 0){
            HashMap<String,Integer> data = new HashMap<>();
            data.put("count",count);
            result.setStatus(200);
            result.setMsg("OK");
            result.setData(data);
        }else {
            result.setStatus(500);
            result.setMsg("服务器返回数据异常");
        }
        return result;
    }

    @Override
    public Result getUserCountByMount(){
        Result result = new Result();
        Integer count = userMapper.getUserCountByMount();
        if(count >= 0){
            HashMap<String,Integer> data = new HashMap<>();
            data.put("count",count);
            result.setStatus(200);
            result.setMsg("OK");
            result.setData(data);
        }else {
            result.setStatus(500);
            result.setMsg("服务器返回数据异常");
        }
        return result;
    }

    @Override
    public Result getAllUserName() {
        Result result = new Result();
        List<Map<String, String>> nameList = userMapper.getAllUserName();
        if (nameList.isEmpty()) {
            result.setStatus(500);
            result.setMsg("结果为空，请检查数据库数据是否完整!");
            return result;
        }
        result.setStatus(200);
        result.setMsg("OK");
        result.setData(nameList);
        return result;
    }
}
